package play.utils.meta.cp; import java.net.URL; import java.util.Collection; import java.util.Map; import java.util.Set; import org.reflections.Configuration; import org.reflections.Reflections; import org.reflections.scanners.SubTypesScanner; import org.reflections.util.ClasspathHelper; import org.reflections.util.ConfigurationBuilder; import play.Logger; import play.Logger.ALogger; import play.utils.meta.ConverterRegistry; import play.utils.meta.convert.Converter; import com.google.common.collect.Maps; public class ClasspathScanningConverterRegistry implements ConverterRegistry { private static ALogger log = Logger.of(ClasspathScanningConverterRegistry.class); private Map<Class<?>, Converter<?>> converters; public ClasspathScanningConverterRegistry(ClassLoader... cls) { this.converters = scan(cls); } @SuppressWarnings("rawtypes") private Map<Class<?>, Converter<?>> scan(ClassLoader... classloaders) { if (log.isDebugEnabled()) log.debug("scan <-"); Collection<URL> urls = ClasspathHelper.forPackage("play.utils.meta.convert", classloaders); if (log.isDebugEnabled()) log.debug("urls : " + urls); Configuration configs = new ConfigurationBuilder().setUrls( urls).addClassLoaders(classloaders).setScanners(new SubTypesScanner(false)); final Reflections reflections = new Reflections(configs); Map<Class<?>, Converter<?>> map = Maps.newHashMap(); Set<Class<? extends Converter>> converterClasses = reflections.getSubTypesOf(Converter.class); if (log.isDebugEnabled()) log.debug("converterClasses : " + converterClasses); for (Class<? extends Converter> converterClass : converterClasses) { try { if (log.isDebugEnabled()) log.debug("converterClass : " + converterClass); Converter converter = converterClass.newInstance(); if (converter != null) { Class<?> keyClass = converter.typeClass(); log.info("Converter:" + keyClass + " : " + converter); map.put(keyClass, converter); } } catch (Exception e) { e.printStackTrace(); } } return map; } @SuppressWarnings("unchecked") @Override public <K> Converter<K> getConverter(Class<K> type) { return (Converter<K>) converters.get(type); } }